<?php

/**
 * @name Mvc
 * @author Roman Metlinskyi <r.metlinskyi@gmail.com>
 * @version alpha 0.5
 */
class Mvc extends My
{

  private static $_mvc;
  private $root;
  private $config;
  private $controller;

  protected function __construct()
  {
    $this->root = my()->directory;
    $this->config = (object) my()->System()->ConfigManager[__CLASS__];

    $this->__init(__FILE__, __CLASS__);
    $this->__preload();
  }

  private function __clone()
  {
    //singleton protected
  }

  public static function Mvc()
  {
    return (!isset(self::$_mvc)) ? (self::$_mvc = new self()) : self::$_mvc;
  }

  /*
   * MVC enter point
   */

  public function Run($configPath = null)
  {

    // Config process
    $this->config->path = $this->__path($this->config->path, $this->root);
    $this->config->application['directory'] =
            $this->config->path . $this->__path("application/", $this->root);

    foreach (array('model', 'view', 'controller') as $name) {
      $this->config->{$name}['directory'] =
              $this->config->path . $this->__path("{$name}s/", $this->root);
    }

    // Default init
    MvcModel::Init((object) $this->config->model);
    MvcView::Init((object) $this->config->view);
    MvcController::Init((object) $this->config->controller);

    // Import application
    $path = $this->config->application['directory'];
    foreach (glob("{$path}*.php") as $filename) {
      require_once $filename;
    }

    // Import model
    $path = $this->config->model['directory'];
    foreach (glob("{$path}*.php") as $filename) {
      require_once $filename;
    }

    // Render controller
    $um = UrlManager::UrlManager();

    $controller = MvcController::Load($um->controllerName);

    $action = new MvcAction($um->actionName, $um->arguments);

    try {
      $action->Invoke($controller);
    } catch (Exception $e) {
      echo $e->getMessage();
    }
  }

  private function __path($path, $root = '')
  {
    return str_replace('/', DIRECTORY_SEPARATOR, str_replace('~/', $root, $path));
  }

}
